#include "fake.h"
#include "log.h"
#include "Lock.h"
#include <time.h>
#include <stdlib.h>
#include <unistd.h>

static int total_ret = 0;
static int total_send = 0;
static const int g_data_size = 2048;
static uint8_t data[2048];

static void process_uintr(void)
{
    while (get_num_of_ocall_and_eret() != 0)
    {
        total_ret += 1;
        if (total_ret % (int)OUTPUT_FREQUENCY == 0)
        {
            LOG("total_ret=%d\n", total_ret);
        }
        drop_obuffer_data();
    }
    
    atomic_write_uint32(&has_ret, 0);
    // TEST_PRINT("has_ret=false, total_ret=%d\n", total_ret);
}

void fake_normal(void *shared_buffer, notify_enclave_func_ptr notify_enclave, int pid)
{
    usleep(1000 * 30);//确保子进程已经启动
    total_send = 0;
    total_ret = 0;

    // 设置随机种子
    srand((unsigned)time(NULL));
    register_um((uint64_t)shared_buffer, UM_SIZE);
    init_um(false);


    while (total_send < NUM_OF_TESTS)
    {
        int data_size = rand() % g_data_size;
        int64_t op_id = async_ecall(0, (void *)data, data_size);
        if (op_id != -1)
        {
            total_send += 1;
            notify_enclave(pid);
        }
        if (op_id < 0 && get_num_of_ocall_and_eret() > 0)
        { // failed and has eret or ocall
            process_uintr();
        }
        if (atomic_read_uint32(&has_ret))
        {
            process_uintr();
        }
    }

    while (total_ret < total_send)
        process_uintr();

    LOG("exit, total send = %d, total ret = %d\n", total_send, total_ret);
    TEST_ASSERT_INFO(get_num_of_ecall_and_oret() == 0, "get_num_of_ocall_and_oret() != 0");
    TEST_PRINT("exit, total send = %d\n", total_send);
    return;
}
